﻿//using code for shaped window form from: http://vckicks.110mb.com/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using log4net;
using log4net.Config;
using System.Timers;
using System.Net;
using System.Threading;
using WHT_Auth;

namespace WHO_Auth_TNG_Win {
    public partial class MainWindow : Form {

        public Auth auth;
        private static readonly ILog log = LogManager.GetLogger("WHO-Auth TNG");
        private Point mouseOffset;
        private bool isMouseDown = false;
        private bool minimizedAtStart = false;
        private bool isKilled = false;
        private LogViewHandler lvh;
        public AuthCode savedAuthCode;
        private bool showLogout = false;
        public const int VERSION = 1;

        public MainWindow() {
            log.Info("Starting program");
            InitializeComponent();

            //Add LogViewHandler
            lvh = new LogViewHandler(this.listView1);
            log4net.Config.BasicConfigurator.Configure(lvh);
            this.listView1.HandleCreated += new EventHandler(lvh.showRememberedEvents);

            //When textStatus is loaded it should show the connection status that was sent when it wasn't visible
            infoStatus.HandleCreated += new EventHandler(this.showSavedInfo);

        
            //Disable SSL
            ServicePointManager.CertificatePolicy = auth;


            //Hide tray icon
            notifyIcon1.Visible = false;
            auth = new Auth(this);
            
            //Read password from settings
            if (!WHT_Auth.Properties.Settings.Default.password.Equals("")) {
                auth.password = Base64.Decode(WHT_Auth.Properties.Settings.Default.password);
            }

            //Handle auth state changes
            auth.AuthStateChange += new Auth.AuthStateChangeHandler(handleAuthStateChange);

            //Check saved settings and show appropiate windows
            if (WHT_Auth.Properties.Settings.Default.username.Equals("")) {
                //Username not set -> Open options dialog
                var startup = new StartOptions(this);
                startup.ShowDialog();
            } else {
                if (WHT_Auth.Properties.Settings.Default.password.Equals("")) {
                    //Password not set -> Open password dialog
                    PasswordDialog pd = new PasswordDialog(auth);
                    pd.ShowDialog();
                }
                auth.initialize();
                if (WHT_Auth.Properties.Settings.Default.startMinmized) {
                    WindowState = FormWindowState.Minimized;
                } else {
                    minimizedAtStart = true;
                }
            }
        }



        

        

        #region handle Update Info

        delegate void UpdateInfo(AuthCode newState);

        public void handleAuthStateChange(AuthCode newState) {
            if (infoStatus.IsHandleCreated) {
                infoStatus.BeginInvoke(new UpdateInfo(this.setInfo), newState);
            } 
                savedAuthCode = newState;
        }

        private void showSavedInfo(Object sender, EventArgs ev) {
            infoStatus.BeginInvoke(new UpdateInfo(this.setInfo), savedAuthCode);
        }

        private void setInfo(AuthCode newState) {
            switch (newState) {
                case AuthCode.CONNECTED:
                case AuthCode.RETRIEVAL_OK:
                    try {
                        infoStatus.Text = "Connected";
                    } catch (Exception) {
                    }
                    break;
                case AuthCode.CHECKING_CONNECTION:
                    infoStatus.Text = "Checking connection status...";
                    break;
                case AuthCode.CONNECTION_UNKNOWN:
                    infoStatus.Text = "Connection status unknown";
                    break;
                case AuthCode.DEACTIVATED:
                    infoStatus.Text = "WHT-Auth is inactive";
                    break;
                case AuthCode.ERROR:
                    infoStatus.Text = "An unknown error occured";
                    break;
                case AuthCode.LOGGED_IN:
                    infoStatus.Text = "Successfully logged in";
                    break;
                case AuthCode.LOGGED_OUT:
                    infoStatus.Text = "Successfully logged out";
                    break;
                case AuthCode.LOGGING_IN:
                    infoStatus.Text = "Logging in...";
                    break;
                case AuthCode.LOGIN_FAILED:
                    infoStatus.Text = "Login failed - Interval set to 60 seconds"; //why is constant in auth not accessible?
                    break;
                case AuthCode.LOGIN_REJECTED:
                    infoStatus.Text = "Credentials rejected - Will try again in " + (Auth.TIMER_CREDENTIALS_REJECTED_INTERVAL/1000) + "s";
                    break;
                case AuthCode.LOGIN_UNKNOWN:
                    infoStatus.Text = "Login attempted but success is unknown";
                    break;
                case AuthCode.NOT_CONNECTED:
                    infoStatus.Text = "Not connected";
                    break;
                case AuthCode.RETRIEVAL_FAILED:
                    infoStatus.Text = "Connected but connection information retrieval failed";
                    break;
                case AuthCode.RETRIEVING_INFO:
                    infoStatus.Text = "Retrieving connection information";
                    break;
                case AuthCode.CONNECTION_CHECK_FAILED:
                    infoStatus.Text = "Error checking connection status";
                    break;
            }

            if (notifyIcon1.Visible) {
                try {
                    notifyIcon1.Text = "WHT-Auth - " + infoStatus.Text;
                } catch (Exception) { }
            }

            if (auth.isConnected() && newState != AuthCode.CHECKING_CONNECTION) {
                showLogout = true;
                buttonLogin.Text = "Logout";
            } else {
                if (newState != AuthCode.CHECKING_CONNECTION) {
                    showLogout = false;
                    buttonLogin.Text = "Login";
                }
            }

            if (newState == AuthCode.LOGIN_REJECTED
                || newState == AuthCode.LOGIN_FAILED
                || newState == AuthCode.ERROR
                || newState == AuthCode.CONNECTION_CHECK_FAILED
                || newState == AuthCode.KILLED
                ) {
                infoStatus.BackColor = Color.Red;
                infoStatus.ForeColor = Color.White;
            } else {
                infoStatus.BackColor = Color.FromArgb(180, 255, 130);
            }
        }

        #endregion

        private void Form1_Load(object sender, EventArgs e) {
        }

        #region buttons

        private void buttonLogin_Click(object sender, EventArgs e) {
            if (showLogout) {
                log.Info("Logout requested");
                auth.doLogout();
            } else {
                auth.attemptLogin();
                log.Info("Login requested");
            }
        }

        private void buttonInfo_Click(object sender, EventArgs e) {
            WHT_Auth.Info i  = new WHT_Auth.Info();
            i.ShowDialog(this);
        }

        private void buttonOptions_Click(object sender, EventArgs e) {
            OptionsDialog od = new OptionsDialog(this, false);
            od.ShowDialog(this);
        }

        private void button1_Click(object sender, EventArgs e) {
           quit();
        }

        private void buttonSendToTray_Click(object sender, EventArgs e) {
            sendToTray();
        }

#endregion



        #region handle moving of window


        private void MainWindow_MouseDown(object sender, MouseEventArgs e) {
            int xOffset;
            int yOffset;

            if (e.Button == MouseButtons.Left) {
                xOffset = -e.X - SystemInformation.FrameBorderSize.Width;
                yOffset = -e.Y - SystemInformation.CaptionHeight -
                    SystemInformation.FrameBorderSize.Height;
                mouseOffset = new Point(xOffset + 4, yOffset + 30);
                isMouseDown = true;
            }
        }

        private void MainWindow_MouseUp(object sender, MouseEventArgs e) {
            // Changes the isMouseDown field so that the form does
            // not move unless the user is pressing the left mouse button.
            if (e.Button == MouseButtons.Left) {
                isMouseDown = false;
            }
        }

        private void MainWindow_MouseMove(object sender, MouseEventArgs e) {
            if (isMouseDown) {
                Point mousePos = Control.MousePosition;
                mousePos.Offset(mouseOffset.X, mouseOffset.Y);
                Location = mousePos;
            }
        }

        #endregion


        #region traybar stuff

        private void sendToTray() {
            Hide();
            notifyIcon1.Visible = true;
            log.Info("Minimizing to tray");
        }
        private void removeFromTray() {
            Show();
            WindowState = FormWindowState.Normal;
            notifyIcon1.Visible = false;
            log.Info("Restoring from tray");
            Focus();
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) {
            removeFromTray();
        }

        private void MenuQuit_Click(object sender, EventArgs e) {
            notifyIcon1.Visible = false;
            quit();
        }

        private void menuRestore_Click(object sender, EventArgs e) {
            removeFromTray();
        }

        private void menuDisableTimer_Click(object sender, EventArgs e) {
            if (auth.timerRunning()) {
                auth.stopTimer();
            } else {
                if (!isKilled)
                    auth.startTimer();
            }
        }

        #endregion

        #region handle window state changes

        private void MainWindow_VisibleChanged(object sender, EventArgs e) {
            if (WHT_Auth.Properties.Settings.Default.startMinmized) {
                if (!minimizedAtStart) {
                    minimizedAtStart = true;
                    Hide();
                    notifyIcon1.Visible = true;
                    log.Info("Starting minimized");
                }
            }
        }

        private void quit() {
            if (auth.isConnected() && WHT_Auth.Properties.Settings.Default.quitAction == 0) {
                WHT_Auth.LogoutAtQuit laq = new WHT_Auth.LogoutAtQuit(auth);
                laq.ShowDialog();
            } else if (WHT_Auth.Properties.Settings.Default.quitAction == 2) {
                auth.doLogout();
            }
            auth.stopAll();
            log.Info("Closing program");
            notifyIcon1.Visible = false;
            notifyIcon1.Dispose();
            System.Environment.Exit(0);
        }

        private void MainWindow_Resize(object sender, EventArgs e) {
            if (FormWindowState.Minimized == WindowState && minimizedAtStart) {
                sendToTray();
            }
        }

        protected override bool ShowWithoutActivation {
            get {
                if (WHT_Auth.Properties.Settings.Default.startMinmized) {
                    return true;
                } else {
                    return false;
                }
            }
        }

        #endregion

        private void notifyIcon1_MouseClick(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Left) {
                removeFromTray();
            }
        }


    }


}
